//
//  RecordDiagnosisService.m
//  MobileChecker
//
//  Created by Lymons on 15-1-8.
//  Copyright (c) 2015年 Lymons. All rights reserved.
//

#import "RecordDiagnosisService.h"
#import <AVFoundation/AVFoundation.h>
#import "SystemUtils.h"

NSString * const kRecodeFileName = @"RecordedFile";

@interface RecordDiagnosisService ()

@property (nonatomic, strong) NSURL *recordedFile;
@property (nonatomic, strong) AVAudioRecorder *recorder;
@property (nonatomic, strong) NSTimer *updateRecorderMetersTimer;

@end

@implementation RecordDiagnosisService

- (NSString *)dbString:(CGFloat)db
{
    return [NSString stringWithFormat:@"%d DB", (int)db];
}

- (void)startCheck:(id<RACSubscriber>)subscriber
{
    if (![self prepareToRecord]) {
        return;
    }
    
    self.recorder = [[AVAudioRecorder alloc] initWithURL:self.recordedFile settings:nil error:nil];
    self.recorder.meteringEnabled = YES;
    [self.recorder prepareToRecord];
    [self.recorder record];
    
    if (BELOWIOS7) {
        self.updateRecorderMetersTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
                                                                          target:self selector:@selector(updateRecorderMeters:)
                                                                        userInfo:nil repeats:YES];
        
    } else if ([[AVAudioSession sharedInstance] respondsToSelector:@selector(requestRecordPermission:)]) {
        [[AVAudioSession sharedInstance] performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
            if (granted) {
                self.updateRecorderMetersTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
                                                                                  target:self selector:@selector(updateRecorderMeters:)
                                                                                userInfo:nil repeats:YES];
            } else {
                dispatch_async(dispatch_get_main_queue(), ^{
//                    [[[UIAlertView alloc] initWithTitle:@"Microphone Access Denied"
//                                                message:@"This app requires access to your device's Microphone.\n\nPlease enable Microphone access for this app in Settings / Privacy / Microphone\n\n* The operation will restart this app."
//                                               delegate:nil
//                                      cancelButtonTitle:@"Dismiss"
//                                      otherButtonTitles:nil] show];
                    NSString *message = [NSString stringWithFormat:@"マイクをONにしてください。\n設定 > プライバシー > マイク > %@で、マイクの利用許可を ON にしてください。\n\nこの操作によってアプリが再起動になります。",
                                                                    [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]];
                    [[[UIAlertView alloc] initWithTitle:@"マイク禁止"
                                                message:message
                                               delegate:nil
                                      cancelButtonTitle:@"了解"
                                      otherButtonTitles:nil] show];
                });
                
                [self endCheckOnTimer:nil];
                [self deleteRecoreFile];
                [subscriber sendNext:@(YES)];
                [subscriber sendCompleted];
            }
        }];
    }

}

- (void)endCheckOnTimer:(id<RACSubscriber>)subscriber
{
    [self.recorder stop];
    self.recorder = nil;
    [self.updateRecorderMetersTimer invalidate];
}

#pragma mark - utils

- (BOOL)prepareToRecord
{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    
    BOOL audioAvailable = audioSession.inputAvailable;
    if (audioAvailable == NO) {
        return NO;
    }
    
    NSError *sessionError;
    [audioSession setCategory:AVAudioSessionCategoryRecord error:&sessionError];
    
    if(audioSession == nil) {
        NSLog(@"Error creating session: %@", [sessionError description]);
        return NO;
    } else {
        [audioSession setActive:YES error:nil];
    }
    
    if (self.recordedFile == nil) {
        NSString *fileName = kRecodeFileName;
        self.recordedFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingString:fileName]];
    }
    
    return YES;
}

- (void)updateRecorderMeters:(NSTimer *)timer
{
    [self.recorder updateMeters];
    
    // 方案１：
    float level;
    float minDecibels = -80.0f;
    float decibels = [self.recorder averagePowerForChannel:0];
    if (decibels < minDecibels) {
        level = 0.0f;
    } else if (decibels >= 0.0f) {
        level = 1.0f;
    } else {
        float root = 2.0f;
        float minAmp = powf(10.0f, 0.05f * minDecibels);
        float inverseAmpRange = 1.0f / (1.0f - minAmp);
        float amp = powf(10.0f, 0.05f * decibels);
        float adjAmp = (amp - minAmp) * inverseAmpRange;
        level = powf(adjAmp, 1.0f / root);
    }
    self.volumeDbString = [self dbString:level * 120];
    
    // 方案２：
//    float avg = [self.recorder averagePowerForChannel:0];
//    float minValue = -60;
//    float range = 60;
//    float outRange = 100;
//    if (avg < minValue) {
//        avg = minValue;
//    }
//    
//    float decibels = (avg + range) / range * outRange;
//
//    self.volumeDbString = [self dbString:decibels];
//    NSLog(@"volumeDbString = %@", self.volumeDbString);
}

- (void)deleteRecoreFile
{
    NSError *error;
    NSFileManager *defaultManager = [NSFileManager defaultManager];
    [defaultManager removeItemAtURL:self.recordedFile error:&error];
    if (error) {
        NSLog(@"%s %@",__PRETTY_FUNCTION__, error);
    }
}

@end
